package cn.four.hqServer.modules.withdraw.service.impl;


import cn.four.hqServer.common.entity.HqCardInfo;
import cn.four.hqServer.common.entity.HqTranUser;
import cn.four.hqServer.common.entity.HqUserInfo;
import cn.four.hqServer.common.entity.HqYhTran;
import cn.four.hqServer.common.result.Result;
import cn.four.hqServer.modules.transfer.service.ZnbIHqCardInfoService;
import cn.four.hqServer.modules.transfer.service.ZnbIHqTranUserService;
import cn.four.hqServer.modules.transfer.service.ZnbIHqUserInfoService;
import cn.four.hqServer.modules.withdraw.dto.WithdrawDto;
import cn.four.hqServer.modules.withdraw.mapper.XqxHqCardInfoMapper;
import cn.four.hqServer.modules.withdraw.service.XqxIHqYhTranService;
import cn.four.hqServer.modules.withdraw.service.xqxIHqWithdrawService;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * @author xqx
 * @description 针对取款操作的数据库操作Service实现
 * @createDate 2023-02-23 14:01:37
 */
@Service("WithdrawService")
public class xqxHqWithdrawServiceImpl implements xqxIHqWithdrawService {

    @Autowired
    private XqxHqCardInfoMapper xqxHqCardInfoMapper;


    @Autowired
    private ZnbIHqTranUserService tranUserService;

    @Autowired
    private XqxIHqYhTranService yhTranService;

    @Autowired
    private ZnbIHqUserInfoService  userInfoService;

    @Autowired
    private ZnbIHqCardInfoService cardInfoService;

    //    记录输入密码次数
    private int num = 0;
    //记录账户余额
    private BigDecimal v;


    /**
     * 检查账户状态
     * @param withdrawDto
     * @return
     */
    @Override
    public int checkStateByCardId(WithdrawDto withdrawDto) {
        return xqxHqCardInfoMapper.checkStateByCardId(withdrawDto);
    }


    /**
     * 比较密码
     * @param withdrawDto
     * @return
     */
    @Override
    public boolean checkCardPassword(WithdrawDto withdrawDto) {

//        根据银行卡号得到账户信息
        HqCardInfo fkr = cardInfoService.getById(withdrawDto.getCardId());
//        根据账户信息的身份证号得到用户信息
        HqUserInfo fkrInfo = userInfoService.getById(fkr.getUserId());

//        用md5工具类转换前端传过来的密码然后比较
        String salt = (fkrInfo.getSalt() != null) ? fkrInfo.getSalt() : "";
        String md5Hex = DigestUtils.md5Hex(withdrawDto.getPassword() + salt);
        if (md5Hex.equals(fkr.getPassword())) {
            return true;
        }else {
            System.out.println("ok");
            return false;
        }
    }

    /**
     * 比较取款金额和账户余额
     * @param withdrawDto
     * @return
     */
    @Override
    public boolean compareBalance(WithdrawDto withdrawDto) {
        v = xqxHqCardInfoMapper.compareBalance(withdrawDto);
        if (withdrawDto.getWithdrawAmount().compareTo(v) > 0) {
            return false;
        }else {
            return true;
        }
    }

    /**
     * 插入交易数据信息
     * @param withdrawDto
     * @return
     */
    @Override
    @Transactional(isolation=Isolation.REPEATABLE_READ)
    public boolean saveBalance(WithdrawDto withdrawDto) {
//        获取账户余额
        v = xqxHqCardInfoMapper.compareBalance(withdrawDto);
//        用一个用户流水表实体记录数据
        HqTranUser hqTranUser = new HqTranUser();
        hqTranUser.setCardId(withdrawDto.getCardId());
        hqTranUser.setBusinessType(3);
        hqTranUser.setTranAmount(withdrawDto.getWithdrawAmount().negate());
        hqTranUser.setTranName("银行现金账户");
        hqTranUser.setTranCardId("10000001");
        hqTranUser.setNotes("柜台取款");
//        获取当前时间
        Date localdate = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        Instant instant = localdate.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        hqTranUser.setTranTime(localDateTime);
//        计算取款后的账户余额
        BigDecimal c = v.subtract(withdrawDto.getWithdrawAmount());
        hqTranUser.setTranAfterAmount(c);
//        xqxHqCardInfoMapper.insertTU(hqTranUser);
        tranUserService.save(hqTranUser);



//        用一个现金流水表实体记录数据
        HqYhTran hqYhTran = new HqYhTran();
        hqYhTran.setTranTime(localDateTime);
        hqYhTran.setBusinessType(3);
        hqYhTran.setTranAmount(withdrawDto.getWithdrawAmount().negate());
        hqYhTran.setCardId(withdrawDto.getCardId());
//        xqxHqCardInfoMapper.insertT(hqYhTran);
        yhTranService.save(hqYhTran);


//        更新账户余额
        HqCardInfo cardInfo = new HqCardInfo();
        cardInfo.setBalance(c);
        cardInfo.setCardId(withdrawDto.getCardId());
        xqxHqCardInfoMapper.updateCI(cardInfo);
        return true;
    }

    /**
     * 冻结账户
     * @param withdrawDto
     * @return
     */
    @Override
    public boolean updateState(WithdrawDto withdrawDto) {
        HqCardInfo cardInfo = new HqCardInfo();
        cardInfo.setCardId(withdrawDto.getCardId());
        int  i = xqxHqCardInfoMapper.updateCardState(cardInfo);
        if (i == 1) {
            return true;
        }else {
            return false;
        }
    }


    /**
     * 整合所有操作
     * @param withdrawDto
     * @return
     */
    @Override
    public Result withdrawMoney(WithdrawDto withdrawDto)  {
        //        1.判断账户状态是否可以进行取款 正常-0、透支-1、冻结-2、注销-3
        int i = checkStateByCardId(withdrawDto);
        if (i == 0) {
            //        2.判断账户取款密码是否正确
            boolean b = checkCardPassword(withdrawDto);
            if (b) {
                //        3.判断账户取款金额<=账户余额
                boolean b1 = compareBalance(withdrawDto);
                if (b1) {
                    //       4.对取款操作进行记录
                    boolean b2 = saveBalance(withdrawDto);
                    if(b2){
//                      在成功后重置可输入密码次数
                        num = 0;
                        return Result.success("取款成功");
                    }else {
                        return Result.error("交易失败，系统错误");
                    }

                }
                else {
                    return Result.error("取款金额大于账户余额，您的余额为"+v+"元");
                }

            }
            else {
                num++;
//                错误等于三次，账户冻结
                if (num == 3) {
//                  冻结账户
                    updateState(withdrawDto);
                    return Result.error("取款密码输入错误3次，"+"账户已冻结");
                }else {
                    return Result.error("取款密码输入错误，" + "还有" + (3 - num) + "次输入机会，之后账户将冻结");
                }
            }

        }
        else if(i == 1){
            return Result.error("该账户处于透支状态");
        }
        else if(i == 2){
            return Result.error("该账户处于冻结状态");
        }
        else if(i == 3){
            return Result.error("该账户处于注销状态");
        }
        else {
            return Result.error("交易失败");
        }
    }


}